<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\command\kuaishou;

use app\command\BaseWork;
use app\enum\BatchProjectEnum;
use app\enum\ConfigEnum;
use app\enum\KuaiShouEnum;
use app\model\KsBatchProjectModel;
use app\service\BaseService;
use app\service\batch\kuaishou\CreateContentService;
use think\Collection;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

class BatchContentCreateWork extends BaseWork
{
    protected function configure()
    {
        // 指令配置
        $this->setName('ks_batch_content_create_work')
            ->addArgument('id', Argument::OPTIONAL, 'id');
        // 设置参数
        $this->setDescription('快手智能化搭建生成结构体');
    }

    /**
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function execute(Input $input, Output $output)
    {
        set_time_limit(0);
        ini_set('memory_limit', '-1');
        $this->getOutputMessage('快手智能化搭建生成结构体开始');
        $id = intval($input->getArgument('id'));
        $list = $this->getTaskList($id);
        if ($list) {
            foreach ($list as $model) {
                $this->getOutputMessage('快手智能化搭建生成结构体' . $model->getKey() . '开始');
                $lockKey = sprintf(ConfigEnum::CACHE_CONFIG[KuaiShouEnum::BATCH_CONFIG_LOCK_KEY]['batch_content'], $model->getKey());
                if (! BaseService::lock($lockKey, $model->getKey(), 24 * 3600)) {
                    $this->getOutputMessage('快手智能化搭建生成结构体' . $model->getKey() . '加锁失败');
                    continue;
                }
                try {
                    Db::startTrans();
                    $createService = new CreateContentService();
                    if (! $createService->createContent($model)) {
                        throw new \Exception(CreateContentService::getError(0));
                    }
                    Db::commit();
                    // 加入处理素材的队列 && 广告计划队列
                    if ($createService->buildService->isNewCampaign()) {
                        // 已建计划直接执行组
                        $createService->pushKsCampaignList($createService->campaignIds);
                    } else {
                        $createService->pushKsUnitList(array_column($createService->unitIds, 'id'));
                    }
                    $createService->pushKsMaterialList($createService->creativeIds);

                    $this->getOutputMessage('快手智能化搭建生成结构体' . $model->getKey() . '结束');
                    usleep(rand(100, 900));
                } catch (\Exception $e) {
                    Db::rollback();
                    $model->setAttr('status', BatchProjectEnum::PROJECT_STATUS_CONTENT_FALSE);
                    $model->save();
                    $this->getOutputMessage($e->getMessage());
                    $this->getOutputMessage($e->getFile() . '[' . $e->getLine() . ']');
                    $this->getOutputMessage($e->getTraceAsString());
                }
            }
        }
        $this->getOutputMessage('快手智能化搭建生成结构体结束');
    }

    /**
     * 查找未搭建数据.
     *
     * @return array|Collection|KsBatchProjectModel[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function getTaskList(int $id = 0)
    {
        if ($id) {
            $where[] = ['id', '=', $id];
        } else {
            $where = [
                ['status', '=', BatchProjectEnum::STATUS_WAIT],
            ];
        }
        return (new KsBatchProjectModel())->where($where)->select();
    }
}
